package com.qubyer.widget.adapter

import android.content.Context
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView

abstract class RvAdapter<T, VH : RecyclerView.ViewHolder>(val dataList: ArrayList<T> = ArrayList()) : RecyclerView.Adapter<VH>() {

    var mContext: Context? = null

    override fun getItemCount(): Int {
        return dataList.size
    }

    override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
        super.onAttachedToRecyclerView(recyclerView)
        mContext = recyclerView.context
    }

    override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
        super.onDetachedFromRecyclerView(recyclerView)
        mContext = null
    }

    open fun setDataList(list: List<T>?) {
        val result = DiffUtil.calculateDiff(object : DiffUtil.Callback() {
            override fun getOldListSize(): Int {
                return dataList.size
            }

            override fun getNewListSize(): Int {
                return list?.size ?: 0
            }

            override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
                return isSameKeyItem(dataList[oldItemPosition], list!![newItemPosition])
            }

            override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
                return isSameItem(dataList[oldItemPosition], list!![newItemPosition])
            }
        })
        dataList.clear()
        list?.let {
            dataList.addAll(list)
        }
        result.dispatchUpdatesTo(this)
    }

    open fun isSameKeyItem(oldItem: T, newItem: T): Boolean {
        return oldItem == newItem
    }

    open fun isSameItem(oldItem: T, newItem: T): Boolean {
        return oldItem == newItem
    }

    open fun getItem(position: Int): T {
        return dataList[position]
    }

    open fun addDataList(list: List<T>?) {
        list?.let {
            val size = dataList.size
            dataList.addAll(it)
            notifyItemRangeInserted(size, it.size)
        }
    }

    open fun addData(data: T) {
        dataList.add(data)
        notifyItemInserted(dataList.size - 1)
    }

    open fun replaceData(index: Int, data: T) {
        dataList[index] = data
        notifyItemChanged(index)
    }

    open fun remove(data: T) {
        val index = dataList.indexOf(data)
        if (index >= 0) {
            dataList.removeAt(index)
            notifyItemRemoved(index)
        }
    }
}

